<template>
  <div class="v-editor-model-dropdown-search">
    <MDropdown
      ref="dropdown"
      :disabled="row.readonly || isModelDisabled"
      @visible-change="handleVisibleChange"
    >
      <div
        class="g-jc-sb g-pd-l-8 g-pointer"
        @contextmenu="propertyModelContextMenu($event, row.value as ModelValue)"
      >
        <div
          v-if="isEncrypted"
          class="g-flex-1 g-one-line"
        >
          <span v-if="containTermName.length">
            <span
              v-for="(item, index) in containTermName"
              :key="index"
            >
              <span
                v-if="item.isTerm"
                class="show-underline"
                @contextmenu.stop="event => showDetailTerm(event, item.name)"
              >
                {{ item.name }}
              </span>
              <span v-else>{{ item.name }}</span>
            </span>
          </span>
          <span v-else>{{ desensitize(modelValue) }}</span>
        </div>
        <div
          v-else
          class="g-flex-1 g-one-line"
        >
          <img
            v-if="icon"
            :src="icon"
            style="height: 16px"
            alt=""
          />
          <span v-if="containTermName.length">
            <span
              v-for="(item, index) in containTermName"
              :key="index"
            >
              <span
                v-if="item.isTerm"
                class="show-underline"
                @contextmenu.stop="event => showDetailTerm(event, item.name)"
              >
                {{ item.name }}
              </span>
              <span v-else>{{ item.name }}</span>
            </span>
          </span>
          <span v-else>{{ modelValue }}</span>
        </div>
        <div
          v-if="selected && !row.readonly && !isModelDisabled"
          class="g-flex-0 g-pd-lr-4"
        >
          <img
            src="statics/icons/app/iconlist2.png"
            @click="handleClick"
          />
        </div>
      </div>
      <template #dropdown>
        <div>
          <el-input
            v-model="model.keyword"
            v-focus
            placeholder="搜索"
            clearable
            class="_search-input"
            size="small"
            :prefix-icon="Search"
            @input="handleInput"
          />
        </div>
        <InfiniteScroll
          :loadData="handleScroll"
          :delay="100"
          :distance="50"
          :immediate="false"
          :disabled="model.loadedAll"
          style="min-height: 10px; max-height: 200px; overflow: auto"
        >
          <div
            v-if="model.list.length === 0"
            class="g-tc"
            style="line-height: 30px; color: #999999"
          >
            {{ model.loading ? $t("加载中") + "..." : $t("无匹配项") }}
          </div>
          <template v-else>
            <MDropdownMenuItem
              v-if="props.row.value && props.row.nullable"
              @click="handleClearValue"
            >
              <div>
                <img
                  src="/statics/images/sysml/iconnone.svg"
                  style="height: 16px"
                  onerror="this.src='statics/images/sysml/Stereotype.svg'"
                />
                <span class="g-pd-lr-8">{{ $t("空") }}</span>
              </div>
            </MDropdownMenuItem>
            <MDropdownMenuItem
              v-for="(item, index) in model.list"
              :key="index"
              :class="{ _selected: item.id === (row.value as ModelValue)?.id }"
              @click="handleClickItem(item)"
            >
              <img
                :src="item.icon"
                style="height: 16px"
              />
              <span class="g-pd-lr-8">{{ item.label }}</span>
            </MDropdownMenuItem>
          </template>
        </InfiniteScroll>
        <!-- <div v-loading="loading" >

        </div> -->
      </template>
    </MDropdown>
  </div>
</template>
<script lang="ts" setup>
import { ref, computed, inject, Ref, reactive, onBeforeMount } from "vue";
import { ModelValue, PropertyRow } from "../../types";
import MDropdown from "@/common/dropdown/Dropdown.vue";
import MDropdownMenuItem from "@/common/dropdown/DropdownMenuItem.vue";
import { propertyUtil } from "../../PropertyUtil";
import { Search } from "@element-plus/icons";
import { DropdownModel } from "@/common/dropdown/DropdownModel";
import { propertyModelContextMenu } from "../propertyUtil";
import InfiniteScroll from "@/common/InfiniteScroll/InfiniteScroll.vue";
import { ChooseElementByPageModel, ListItem } from "@/common/ChooseElementByPageModel";
import { debounce } from "lodash-es";
import { modelUtil } from "@/modules/model/util/ModelUtil";
import { treeUtil } from "../../../modelTree/modelTree/TreeUtil";
import { shapeService } from "@/modules/model/service";
import { desensitize } from "@/util/common";
import { HiddenStatus } from "@/constants/Enums";
import { ContainTermName, splitOriginTextWithTerms, ShapeKey } from "@/mdesign-lib/mdesign-graph.umd.js";
import { showDetailTermCommon } from "@/modules/model/service/termBankService";

const isModelDisabled = inject("isModelDisabled") as Ref<boolean>;

const props = defineProps<{
  row: PropertyRow;
  selected?: boolean;
  encrypted?: boolean;
}>();

const dropdown = ref<{ dropdownModel: DropdownModel } | null>(null);
let propsRowBindShapeIsModelicaShape = ref<boolean>(false);

const isEncrypted = computed(() => {
  const value = props.row.value as ModelValue | null;
  return props.encrypted || value?.hiddenStatus === HiddenStatus.HIDDEN_IN_ENCAP;
});

async function getModeliaShape() {
  if (app?.activeGraph?.shapeMap) {
    for (let [, shape] of app.activeGraph.shapeMap) {
      if (shape.modelId === props.row.modelId && shape.style.isModelicaShape) {
        propsRowBindShapeIsModelicaShape.value = true;
        break;
      }
    }
  } else {
    let shapes = await shapeService.getModelShapesById(app.activeProject!.id, props.row.modelId);
    let portShape = shapes?.find(s => s.shapeKey === ShapeKey.FlowPort && s.style.isModelicaShape);
    if (portShape) {
      propsRowBindShapeIsModelicaShape.value = true;
    }
  }
}
onBeforeMount(() => {
  getModeliaShape();
});

async function loadPageData(page: number, pageSize: number, keyword: string) {
  let res;
  if (propsRowBindShapeIsModelicaShape.value) {
    res = await propertyUtil.getModelicaSelectOptions(props.row, page, pageSize, keyword, app.activeProject!.id);
  } else {
    res = await propertyUtil.getSelectOptions(props.row, page, pageSize, keyword, app.activeProject!.id);
  }
  setTimeout(() => {
    dropdown.value?.dropdownModel.updateMenuStyle();
  }, 100);
  return res;
}
const model = reactive(new ChooseElementByPageModel(loadPageData));
const handleScroll = async function () {
  await model.loadNextPage();
};

// const query = ref('');
// const loading = ref(false);
// const loaded = ref(false);
// const optionList = ref<ModelSeletOption[]>(new Array(1).fill({ name: '', instanceId: '', icon: '' }));
// const filteredOptionList = computed(() => {
//   if (query.value) {
//     return optionList.value.filter(it => it.name.toLowerCase().includes(query.value.toLowerCase()));

//   } else {
//     return optionList.value;

//   }
// });

const modelValue = computed(() => {
  const value = props.row.value as ModelValue | null;
  return value?.name || "";
});
const clientY = ref(0);

const handleClick = (target: MouseEvent) => {
  clientY.value = target.clientY;
};
const icon = computed(() => {
  const value = props.row.value as ModelValue | null;
  return value?.icon || "";
});

const containTermName = computed(() => {
  let _containTermName: ContainTermName[] = [];
  _containTermName = splitOriginTextWithTerms((modelValue.value as string) || "", (props.row.value as ModelValue)?.terms || []);
  return _containTermName;
});

// function loadOptions() {
//   loading.value = true;
//   propertyUtil.getSelectOptions(props.row, 0, 20).then(data => {
//     optionList.value = data;
//     loaded.value = true;
//   }).finally(() => {
//     loading.value = false;
//     nextTick(() => {
//       dropdown.value?.dropdownModel.updateMenuStyle();

//     });
//   });
// }

function showDetailTerm(event: MouseEvent, termText: string) {
  if (props.row.readonly || isModelDisabled?.value) return;
  showDetailTermCommon(event, termText);
}

const handleInput = debounce(function () {
  model.search();
}, 100);

function handleVisibleChange(visible: boolean) {
  if (visible && model.list.length === 0 && !model.loading) {
    model.search();
    // loadOptions();
  }
}

async function handleClickItem(item: ListItem) {
  const project = app.projectManager.getProject(app.activeProject!.id);
  if (project?.config.online) {
    const isVisible = await modelUtil.isVisible(app.activeProject!.id, item.id);
    if (!isVisible) {
      treeUtil.tipModelUnVisible(item.label);
      return;
    }
  }

  propertyUtil.updatePropertyAndFresh(props.row, item.id);
}

function handleClearValue() {
  propertyUtil.updatePropertyAndFresh(props.row, undefined);
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/theme.scss";
.v-editor-model-dropdown-search {
  ._search-input {
    .el-input__wrapper {
      height: 30px;
      box-shadow: unset;
      border-top: 1px solid #e4e4e4;
      border-bottom: 1px solid #e4e4e4;
      border-left: 0;
      border-right: 0;
    }
  }

  ._selected {
    background: $theme-color;
  }
}
</style>
